package com.service.scheduler.server;

import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;

public class SchedulerCreator {
	/**
	 * 创建任务调度器
	 * @param instanceName 调度器实例名称
	 * @param threadCount 调度器最大线程数
	 * @param threadPriority 调度器优先级
	 * @return Scheduler
	 * @throws SchedulerException
	 */
	public static Scheduler createScheduler(String instanceName,int threadCount,int threadPriority) throws SchedulerException{
		Properties props = new Properties();
		props.put("org.quartz.scheduler.instanceName", instanceName);
		props.put("org.quartz.scheduler.rmi.export", "false");
		props.put("org.quartz.scheduler.rmi.proxy", "false");
		props.put("org.quartz.scheduler.wrapJobExecutionInUserTransaction", "false");
		props.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
		props.put("org.quartz.threadPool.threadCount", String.valueOf(threadCount));
		props.put("org.quartz.threadPool.threadPriority", String.valueOf(threadPriority));
		props.put("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread", "true");
		props.put("org.quartz.jobStore.misfireThreshold", "60000");
		props.put("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore");
		SchedulerFactory schedFactory = new StdSchedulerFactory(props);
		return schedFactory.getScheduler();
	}
		
	/**
	 * 创建任务标识
	 * @param name 任务名称
	 * @param group 任务组名称
	 * @return JobKey
	 */
	public static JobKey createJobKey(String name,String group){
		JobKey jobKey = JobKey.jobKey(name, group);
		return jobKey;
	}
	
	
	/**
	 * 创建定时器标识
	 * @param name 任务名称
	 * @param group 任务组名称
	 * @return TriggerKey
	 */
	public static TriggerKey createTriggerKey(String name,String group){
		TriggerKey triggerKey = TriggerKey.triggerKey(name, group);
		return triggerKey;
	}
	
	
	/**
	 * 创建任务
	 * @param jobKey 任务标识
	 * @param clazz 实现了Job接口的任务类名
	 * @return JobDetail
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static JobDetail createJob(JobKey jobKey,Class clazz){
		JobDetail jobDetail = newJob(clazz).withIdentity(jobKey).build();
		return jobDetail;
	}
	
	
	/**
	 * 创建时间表达式定时器
	 * @param triggerKey 定时器标识
	 * @param cronExpression 时间表达式
	 * @return CronTrigger
	 */
	public static CronTrigger createCronTrigger(TriggerKey triggerKey,String cronExpression){
		CronTrigger cronTrigger= newTrigger().withIdentity(triggerKey).withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build();
		return cronTrigger;
	}
	
	/**
	 * 创建时间表达式定时器</br>
	 * 当需要创建多个触发器时，使用该方法
	 * @param triggerKey 定时器标识
	 * @param cronExpression 时间表达式
	 * @return CronTrigger
	 */
	public static CronTrigger createCronTriggerForJob(JobDetail job, TriggerKey triggerKey,String cronExpression){
		CronTrigger cronTrigger= newTrigger().withIdentity(triggerKey).withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).forJob(job).build();
		return cronTrigger;
	}
	
	/**
	 * 创建普通定时器
	 * @param triggerKey 定时器标识
	 * @param runTime 任务执行时间
	 * @return Trigger
	 */
	public static Trigger createTrigger(TriggerKey triggerKey,Date runTime){
		Trigger trigger = newTrigger().withIdentity(triggerKey).startAt(runTime).build();
		return trigger;
	}
	

	/**
	 * 生成时间表达式
	 * @param date 日期
	 * @return cronExpression
	 */
	public static String createCronExpr(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		String cronExpression = 
				MessageFormat.format("{0} {1} {2} {3} {4} ? *",
						cal.get(Calendar.SECOND), cal.get(Calendar.MINUTE), cal.get(Calendar.HOUR_OF_DAY),
						cal.get(Calendar.DATE), cal.get(Calendar.MONTH)+1);
		return cronExpression;
	}
	
	/**
	 * 生成时间间隔表达式
	 * @param seconds 以秒为单位执行
	 * @return
	 */
	public static String createSecondExpr(int seconds){
		String cronExpression = null;
		cronExpression = MessageFormat.format("*/{0} * * * * ?",seconds);
		return cronExpression;
	}
	
	/**
	 * 生成时间间隔表达式
	 * @param minutes 以分为单位执行
	 * @return
	 */
	public static String createMinuteExpr(int minutes){
		String cronExpression = null;
		cronExpression = MessageFormat.format("0 */{0} * * * ?",minutes);
		return cronExpression;
	}
	
	/**
	 * 生成时间间隔表达式
	 * @param hours 以时为单位执行
	 * @return
	 */
	public static String createHourExpr(int hours){
		String cronExpression = null;
		cronExpression = MessageFormat.format("0 0 0/{0} * * ?",hours);
		return cronExpression;
	}
}
